<?php
/**
 * ����� ��� ������ � �������������
 * 
 *
 *	$workImg = new ImgWriteText(dirname(__FILE__) . '/dem_tpl.jpg');
 *	$workImg->addTextAlignCenter(iconv('windows-1251', 'utf-8', "�����"), 'times.ttf', 40, 500);
 *	$workImg->InsertImageWithResize("i.jpg", 50, 50, 380, 400);
 *	$workImg->save('1231.jpg');
 *	//$workImg->cutAndResize(500, 250, '222.jpg');
 *	//$workImg->resize(100, 100, 'asd.jpg');
 *	
 *	echo "<img src='1231.jpg?" . time() . "'>";
 *
 */

class ImgWriteText{
	/**
	 * � ����� ������������ ����� ��������
	 *
	 * @var string ���� � �����
	 */
	protected $_img_template;
	protected $_lastError = '';
	protected $_imgWorkCopy;
	protected $_imgState;
	
	public function __construct($img_template){
		
		if(!is_file($img_template)){
			throw new Exception("File `{$img_template}` not found.");
		}
		
		$this->_img_template = $img_template;
		$this->_imgState = getimagesize($img_template);
		
		$this->_imgWorkCopy = $this->_createImg($img_template);
		
	}
	
	public function addText($string, $font, $size = 12, $xCoord = 0, $yCoord = 0, $color='0xffffff', $angle = 0){
		
		if(!is_file($font) || strtolower(substr($font, -4)) != '.ttf'){
			
			throw new Exception("Incorrect font file!");
			
		}
		
		$newTrueColorImage = imagecreatetruecolor($this->_imgState[0],$this->_imgState[1]);

		imagefill($newTrueColorImage, 0, 0, 0xffffff);
		
		imagecopyresampled($newTrueColorImage, $this->_imgWorkCopy, 0, 0, 0, 0, $this->_imgState[0], $this->_imgState[1], $this->_imgState[0], $this->_imgState[1]);
		
		imagettftext($newTrueColorImage, $size, $angle, $xCoord, $yCoord, $color, $font, $string);
				
		imagecopyresampled($this->_imgWorkCopy, $newTrueColorImage, 0, 0, 0, 0, $this->_imgState[0], $this->_imgState[1], $this->_imgState[0], $this->_imgState[1]);
		
		imagedestroy($newTrueColorImage);		
		
	}
	
	public function addTextAlignCenter($string, $font, $size = 12, $yCoord = 0, $color='0xffffff', $angle = 0){
		
		$mainCoord = imagettfbbox($size, $angle, $font, $string);
		
		$strHeight = $mainCoord[7] - $mainCoord[1];		
		
		$string = explode("\n", $string);
		
		$diff = abs(ceil($strHeight/sizeof($string)));
		
		$count = sizeof($string);

		$currDiff = 0;
			
		foreach ($string as &$line) {
			
			$line = trim($line);
			
			$coord = imagettfbbox($size, $angle, $font, $line);
			
			$strWidth = $coord[4] - $coord[0];
			
			$emptySpace = $this->_imgState[0] - $strWidth;
			
			$xCoord = floor($emptySpace / 2) - $coord[0] - 1;
			
			if($count > 1){
				
				$yCoord += $diff;
			}
			
			$this->addText($line, $font, $size, $xCoord, $yCoord, $color, $angle);
				
		}	
		
	}
	
	public function InsertImage($newImage,  $dst_x = 0, $dst_y = 0, $src_x = 0, $src_y = 0, $dst_w = 0, $dst_h = 0, $src_w = 0, $src_h = 0){
		
		if(!is_resource($newImage)){
			$newImage = $this->_createImg($newImage);
		}
			
		imagecopyresampled($this->_imgWorkCopy, $newImage, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
		
		imagedestroy($newImage);
		
	}
	
	public function InsertImageWithResize($newImage,  $dst_x = 0, $dst_y = 0, $dst_w = 0, $dst_h = 0){
		
		if(!is_resource($newImage)){
			$newImage = $this->_createImg($newImage);
		}
		
		$newImage = $this->_cutAndResizeImage($newImage, $dst_w, $dst_h);
		
		$state = array(
			imagesx($newImage),
			imagesy($newImage)
		);
		
		imagecopyresampled($this->_imgWorkCopy, $newImage, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $state[0], $state[1]);
		
		imagedestroy($newImage);
	}
	
	public function cutAndResize($width, $height, $savePath = ''){
		
		if($savePath != ''){
			$this->_cutAndResizeImage($this->_imgWorkCopy, $width, $height, $savePath);
		}
		else {
			$this->_imgWorkCopy = $this->_cutAndResizeImage($this->_imgWorkCopy, $width, $height);
		}
	}
	
	public function resize($width, $height, $savePath = ''){
		
		if($savePath != ''){
			$this->_resizeImage($this->_imgWorkCopy, $width, $height, $savePath);
		}
		else {
			$this->_imgWorkCopy = $this->_resizeImage($this->_imgWorkCopy, $width, $height);
		}
	}
	
	protected function &_resizeImage($image, $width, $height, $savePath = null){
				
		if(!is_resource($image)){
			$image = $this->_createImg($image);
		}
		$state = array(
			imagesx($image),
			imagesy($image)
		);
		
		$newTrueColorImage = imagecreatetruecolor($width, $height);
		
		imagecopyresized($newTrueColorImage, $image, 0, 0, 0, 0, $width, $height, $state[0], $state[1]);
		
		//imagedestroy($newTrueColorImage);
		
		if(!is_null($savePath)){
			$ext = substr($savePath, -4);
			
			if($ext == '.png'){
				imagepng($newTrueColorImage, $savePath);
			}
			elseif ($ext == '.gif'){
				imagegif($newTrueColorImage, $savePath);
			}
			else {
				imagejpeg($newTrueColorImage, $savePath, 90);
			}
			imagedestroy($newTrueColorImage);
			imagedestroy($image);
			
		}
		else {
			
			imagedestroy($image);
			
			return $newTrueColorImage;
			
		}
		$return = true;
		return $return;			
	}
	
	protected function &_cutAndResizeImage($image, $width, $height, $savePath = null){
				
		if(!is_resource($image)){
			$image = $this->_createImg($image);
			$white = imagecolorallocate($image, 255, 0, 0);
			imagefill($image, 0, 0, $white);
		}
		$state = array(
			imagesx($image),
			imagesy($image)
		);
		
		$newTrueColorImage = imagecreatetruecolor($width, $height);
		
		//�������� ����� �� ���������/�����������
		$wp = $width/$state[0];
		$hp = $height/$state[1];
		if($wp >= 1 && $hp >= 1){
			if($wp < $hp){
				$image = $this->_resizeImage($image, $width, (int)($state[1] * $wp));
				$shiftX = 0;
				$shiftY = ceil((($state[1] * $wp) - $height)/2);
			}
			else {
				$image = $this->_resizeImage($image, (int)($state[0] * $hp), $height);
				$shiftX = ceil((($state[0] * $hp) - $width)/2);
				$shiftY = 0;
			}
		}
		else {
			
			if($wp > $hp){
				$image = $this->_resizeImage($image, $width, (int)($state[1] * $wp));
				$shiftX = 0;
				$shiftY = ceil((($state[1] * $wp) - $height)/2);
			}
			else {
				$image = $this->_resizeImage($image, (int)($state[0] * $hp), $height);
				$shiftX = ceil((($state[0] * $hp) - $width)/2);
				$shiftY = 0;
			}
			
		}
		
		imagecopyresampled($newTrueColorImage, $image, 0, 0, $shiftX, $shiftY, $width, $height, $width, $height);
		
		//imagedestroy($newTrueColorImage);
		
		if(!is_null($savePath)){
			$ext = substr($savePath, -4);
			
			if($ext == '.png'){
				imagepng($newTrueColorImage, $savePath);
			}
			elseif ($ext == '.gif'){
				imagegif($newTrueColorImage, $savePath);
			}
			else {
				imagejpeg($newTrueColorImage, $savePath, 90);
			}
			imagedestroy($newTrueColorImage);
			imagedestroy($image);
			
		}
		else {
			
			imagedestroy($image);
			
			return $newTrueColorImage;
			
		}
		$return = true;
		return $return;			
	}

	public function resizeWithEmptyBorders($width, $height, $savePath = '', $colorR=0, $colorG=0, $colorB=0){

		if($savePath != ''){
			$this->_resizeWithEmptyBorders($this->_imgWorkCopy, $width, $height, $savePath, $colorR, $colorG, $colorB);
		}
		else {
			$this->_imgWorkCopy = $this->_resizeWithEmptyBorders($this->_imgWorkCopy, $width, $height, $colorR, $colorG, $colorB);
		}
	}

	protected function &_resizeWithEmptyBorders($image, $width, $height, $savePath = null, $colorR=0, $colorG=0, $colorB=0){

		if(!is_resource($image)){
			$image = $this->_createImg($image);
			$color = imagecolorallocate($image, $colorR, $colorG, $colorB);
			imagefill($image, 0, 0, $color);
		}
		$state = array(
			imagesx($image),
			imagesy($image)
		);

		$newTrueColorImage = imagecreatetruecolor($width, $height);

		/*imageAlphaBlending($newTrueColorImage, false);
		imageSaveAlpha($newTrueColorImage, true);
		imageAlphaBlending($image, false);
		imageSaveAlpha($image, true);*/

		$color = imagecolorallocate($newTrueColorImage, $colorR, $colorG, $colorB);
		imagefill($newTrueColorImage, 0, 0, $color);


		//�������� ����� �� ���������/�����������
		$wp = $state[0]/$width;
		$hp = $state[1]/$height;

		$proportion = ($wp > $hp)?$wp:$hp;


		$image = $this->_resizeImage($image, $state[0] / $proportion, $state[1] / $proportion);

		$dst_x = (int)($width - (int)$state[0] / $proportion)/2;

		$dst_y = (int)($height - (int)$state[1] / $proportion)/2;

		imagecopyresampled($newTrueColorImage, $image, $dst_x, $dst_y, 0, 0, $width, $height, $width, $height);

		$color = imagecolorallocate($newTrueColorImage, $colorR, $colorG, $colorB);

		if($dst_x > 0){
			imagefilledrectangle($newTrueColorImage, $width - $dst_x - 1, 0, $width, $height, $color);
		}
		if($dst_y > 0){
			imagefilledrectangle($newTrueColorImage, 0, $height - $dst_y - 1, $width, $height, $color);
		}

		//imagedestroy($newTrueColorImage);

		if(!is_null($savePath)){
			$ext = substr($savePath, -4);

			if($ext == '.png'){
				imagepng($newTrueColorImage, $savePath);
			}
			elseif ($ext == '.gif'){
				imagegif($newTrueColorImage, $savePath);
			}
			else {
				imagejpeg($newTrueColorImage, $savePath, 90);
			}
			imagedestroy($newTrueColorImage);
			imagedestroy($image);

		}
		else {

			imagedestroy($image);

			return $newTrueColorImage;

		}
		$return = true;
		return $return;
	}

	public function save($filename, $quality = 90){
		
		if($filename == ''){
			$filename = time() . '.' . substr($im, -3);
		}
		
		if($this->_imgState[2]=='1'){ imagegif($this->_imgWorkCopy, $filename); }
		if($this->_imgState[2]=='2'){ imagejpeg($this->_imgWorkCopy, $filename, $quality); }
		if($this->_imgState[2]=='3'){ imagepng($this->_imgWorkCopy, $filename); }
		
	}
	
	protected function &_createImg($imagePath){
		
		$state = getimagesize($imagePath);
		
		if($state[2] == '1'){
			$newImg = ImageCreateFromgif($imagePath); 
		}
		elseif($state[2] == '2'){
			$newImg = ImageCreateFromjpeg($imagePath); 
		}	
		elseif($state[2] == '3'){
			$newImg = ImageCreateFrompng($imagePath); 
		}
		else {
			throw new Exception("Img not in extention .jpg, .gif or .png");
		}

		return $newImg;
		
	}
	
	public function __destruct(){
		
		@imagedestroy($this->_imgWorkCopy);
		
	}

}

